package com.sunwhite.herostore.service;

import com.alibaba.fastjson.JSONObject;
import com.sunwhite.herostore.common.async.AsyncOperation;
import com.sunwhite.herostore.common.async.AsyncOperationProcessor;
import com.sunwhite.herostore.config.RedisUtil;
import com.sunwhite.herostore.entity.RankItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Tuple;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;

/**
 * 排行榜服务
 */
public class RankService{
    /**
     * 日志对象
     */
    static private final Logger log = LoggerFactory.getLogger(RankService.class);

    /**
     * 单例对象
     */
    static private final RankService rankService = new RankService();

    /**
     * 私有化类默认构造器
     */
    private RankService() {
    }

    /**
     * 获取单例对象
     *
     * @return 排行榜服务
     */
    static public RankService getInstance() {
        return rankService;
    }

    /**
     * 获取排行榜
     * @param callback
     */
    public void getRank(Function<List<RankItem>,Void> callback){
        if(null==callback){
            return;
        }
        AsyncGetRank asyncGetRank = new AsyncGetRank(){
            @Override
            public void doFinish() {
                callback.apply(this.getRankItemList());
            }
        };
        AsyncOperationProcessor.getInstance().process(asyncGetRank);
    }

    /**
     * 刷新排行榜
     * @param winnerId 赢家ID
     * @param loseId 输家ID
     */
    public void refreshRank(int winnerId,int loseId){
        try(final Jedis jedis = RedisUtil.getJedis()){
            //增加用户的胜利次数和失败次数
            jedis.hincrBy("User_"+winnerId,"Win",1);
            jedis.hincrBy("User_"+loseId,"Lose",1);

            //查看玩家总共赢了多少次
            final String win = jedis.hget("User_" + winnerId, "Win");
            final int winInt = Integer.parseInt(win);

            //修改排名数据
            jedis.zadd("Rank",winInt,String.valueOf(winnerId));

        }catch (Exception ex){
            log.error(ex.getMessage(),ex);
        }
    }

    /**
     * 异步方式获取排行榜
     */
    private class AsyncGetRank implements AsyncOperation {
        /**
         * 排名条目列表
         */
        private List<RankItem> rankItemList = null;

        public List<RankItem> getRankItemList() {
            return rankItemList;
        }

        /**
         * 执行异步操作
         */
        @Override
        public void doAsync() {
            try(Jedis jedis = RedisUtil.getJedis()){
                final Set<Tuple> rank = jedis.zrangeWithScores("Rank", 0, 9);

                rankItemList=new ArrayList<>();
                int rankId=0;

                for (Tuple tuple : rank) {
                    //获取用户ID
                    final int userId = Integer.parseInt(tuple.getElement());

                    //获取用户基本信息
                    final String jsonStr = jedis.hget("User_" + userId, "BasicInfo");

                    if (null==jsonStr){
                        continue;
                    }


                    //创建排名条目
                    final RankItem rankItem = new RankItem();
                    rankItem.rankId=++rankId;
                    rankItem.userId=userId;
                    rankItem.win= (int)tuple.getScore();

                    final JSONObject jsonObject = JSONObject.parseObject(jsonStr);

                    rankItem.userName=jsonObject.getString("userName");
                    rankItem.heroAvatar=jsonObject.getString("heroAvatar");

                    rankItemList.add(rankItem);
                }
            }catch (Exception ex){
                log.error(ex.getMessage(),ex);
            }

        }
    }
}
